package com.cxyd.modules.wcs.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.common.utils.ConvertUtils;
import com.cxyd.modules.api.dto.RcsResult;
import com.cxyd.modules.log.service.SysLogWorkService;
import com.cxyd.modules.wcs.dao.AgvCallbackDao;
import com.cxyd.modules.wcs.dto.AgvCallbackDTO;
import com.cxyd.modules.wcs.entity.AgvCallbackEntity;
import com.cxyd.modules.wcs.entity.AgvTrkEntity;
import com.cxyd.modules.wcs.entity.PostWmsEntity;
import com.cxyd.modules.wcs.entity.TrkEntity;
import com.cxyd.modules.wcs.service.AgvCallbackService;
import com.cxyd.modules.wcs.service.AgvTrkService;
import com.cxyd.modules.wcs.service.PostWmsService;
import com.cxyd.modules.wcs.service.TrkService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.Map;

@Service
public class AgvCallbackServiceImpl extends CrudServiceImpl<AgvCallbackDao, AgvCallbackEntity, AgvCallbackDTO> implements AgvCallbackService {
    @Resource
    private AgvTrkService agvTrkService;
    @Resource
    private TrkService trkService;
    @Resource
    private PostWmsService postWmsService;
    @Resource
    private SysLogWorkService logWorkService;

    @Override
    public QueryWrapper<AgvCallbackEntity> getWrapper(Map<String, Object> params) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RcsResult callbackHandle(AgvCallbackDTO dto) {
        String workName = "CTU执行通知";
        String workProc = "AgvCallbackService.callbackHandle";
        String pCode = "0";
        String pMsg;
//        1.对json报文进行解析(获取reqCode,taskCode,robotCode,method,currentPositionCode)
        String reqCode = dto.getReqCode();
        String taskCode = dto.getTaskCode();
        String robotCode = dto.getRobotCode();
        String method = dto.getMethod();
//        当前站点信息
        String positionCode = dto.getStgBinCode();
//        将dto转换为callback的entity
        AgvCallbackEntity callbackEntity = ConvertUtils.sourceToTarget(dto, AgvCallbackEntity.class);
//        根据taskCode获取任务信息
        AgvTrkEntity task = agvTrkService.getAgvTryByTaskCode(taskCode);
        if (task == null) {
            pCode = "agv_callback_error_001";
            pMsg = "任务单[" + taskCode + "]无执行任务!reqCode[" + reqCode + "]";
            logWorkService.workLogging(workName, taskCode, pCode,
                    pMsg, null, workProc, "WCS系统", 0);
            return new RcsResult().error(reqCode, pMsg);
        }
//        记录车号
        Instant start = Instant.now();
        task.setAgvCode(robotCode);
//        不同的method调用不同的处理逻辑
        if ("start".equals(method)) {
//       1.任务开始(更新任务当前状态0-初始 1-任务下发 2-任务开始 3-搬送中 4-任务完成 9-任务取消)
            agvTrkStart(task, positionCode);
        }
        if ("outbin".equals(method)) {
//      1.走出储位(可认为是下架)
            agvTrkOutbin(task, positionCode);
        }
        if ("end".equals(method)) {
//      1.任务结束
            agvTrkEnd(task, positionCode);
            callbackEntity.setStatus(2);
            baseDao.updateById(callbackEntity);
        }
        if ("getApplyPass".equals(method)) {
//      1.CTU料箱取申请(可能需要任务继续)
            agvTrkApply(task, method, positionCode);
//      将callback记录更新为需任务继续(status=1)
            callbackEntity.setStatus(1);
            baseDao.updateById(callbackEntity);
        }
        if ("putApplyPass".equals(method)) {
//      1.CTU料箱放申请(可能需要任务继续)
            agvTrkApply(task, method, positionCode);
//      将callback记录更新为需任务继续(status=1)
            callbackEntity.setStatus(1);
            baseDao.updateById(callbackEntity);
        }
        if ("cancel".equals(method)) {
//      1.任务取消
        }
//        回调处理完成,记录日志(以任务单维度)
        Instant end = Instant.now();
        Duration times = Duration.between(start, end);
        pMsg = "CTU请求成功,车号[" + robotCode + "],站点[" + positionCode + "],任务单[" + taskCode + "],动作[" + method + "]!";
        logWorkService.workLogging(workName, taskCode, pCode,
                pMsg, null, workProc, "WCS系统", times.toMillis());
        return new RcsResult().success(reqCode);
    }

    /***
     * 任务开始
     * @param task
     */
    private void agvTrkStart(AgvTrkEntity task, String positionCode) {
        String workName = "CTU任务开始";
        String workProc = "AgvCallbackService.agvTrkStart";
        String pCode = "0";
        String pMsg = "小车[" + task.getAgvCode() + "]搬送料箱[" + task.getCtnrCode() + "]起始站点[" + positionCode + "]!method为[start]";
//        start时并未执行该任务,只是说CTU接到有任务而已
        task.setStatus(2);
        task.setData("RCS成功接收到任务,并开始执行!method-[start]");
        task.setUpdateDate(new Date());
        agvTrkService.updateById(task);
//        以料箱维度记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, "WCS系统", 10L);
    }

    /***
     * 走出储位
     * @param task
     */
    private void agvTrkOutbin(AgvTrkEntity task, String positionCode) {
//        通知wms料箱已下架等
        String workName = "料箱走出储位";
        String workProc = "AgvCallbackService.agvTrkOutbin";
        String pCode = "0";
        String pMsg = "小车[" + task.getAgvCode() + "]搬送料箱[" + task.getCtnrCode() + "]到达站点[" + positionCode + "]!method为[outbin]";
//        取放时通知线体完成信号
        task.setStatus(3);//作业申请
        task.setUpdateDate(new Date());
        agvTrkService.updateById(task);
        TrkEntity trkEntity = trkService.selectById(task.getTrkId());
        //      任务接收后上报wms系统[wcs_post_wms]
        PostWmsEntity postWms = new PostWmsEntity();
        postWms.setRequestPk(trkEntity.getRequestPk());
        postWms.setContNo(trkEntity.getContNo());
        postWms.setCurPos(trkEntity.getToPos());
//        类型为[通知]
        postWms.setNoticeType("1");
        postWms.setCode(pCode);
        postWms.setResult(pMsg);
        postWms.setPostSt(0);
        postWms.setCreator(1002L);
        postWms.setUpdateDate(new Date());
//        更新wcs_trk任务为执行中
        trkEntity.setTrkSt(1);
        trkEntity.setComments(pMsg);
        trkEntity.setUpdateDate(new Date());
        trkService.updateById(trkEntity);
        postWmsService.insert(postWms);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, "WCS系统", 10L);
    }

    /***
     * CTU取放申请
     * @param task
     */
    private void agvTrkApply(AgvTrkEntity task, String method, String positionCode) {
        String workName = "CTU取放申请";
        String workProc = "AgvCallbackService.agvTrkApply";
        String pCode = "0";
        String pMsg = "小车[" + task.getAgvCode() + "]到达[" + positionCode + "]!method为[" + method + "]";
//        取放时通知线体完成信号
        task.setStatus(30);//作业申请
        task.setTokenCode(IdUtil.simpleUUID());
        task.setPositionCodePath(positionCode);
        if ("getApplyPass".equals(method)) {
            task.setAgvTyp("1");
        }
        if ("putApplyPass".equals(method)) {
            task.setAgvTyp("2");
        }
        task.setData("CTU小车进行取放申请!");
        task.setUpdateDate(new Date());
        agvTrkService.updateById(task);
        baseDao.updateSignalStatusByStationNo(positionCode);
//        记录日志
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, "WCS系统", 10L);
    }

    /***
     * 任务结束
     * @param task
     */
    private void agvTrkEnd(AgvTrkEntity task, String positionCode) {
        String workName = "CTU任务结束";
        String workProc = "AgvCallbackService.agvTrkEnd";
        String pCode = "0";
        String pMsg = "[step-4]小车[" + task.getAgvCode() + "]搬送料箱[" + task.getCtnrCode() + "]到达站点[" + positionCode + "]!method为[end]";
//      获取[wcs_trk]信息
        task.setStatus(4); //任务完成
        task.setUpdateDate(new Date());
        agvTrkService.updateById(task);
        TrkEntity trkEntity = trkService.selectById(task.getTrkId());
        trkEntity.setTrkSt(2);
        trkEntity.setCurPos(positionCode);
        trkEntity.setUpdater(1002L);
        trkEntity.setUpdateDate(new Date());
        trkService.updateById(trkEntity);
//      任务接收后上报wms系统[wcs_post_wms]
        PostWmsEntity postWms = new PostWmsEntity();
        postWms.setRequestPk(trkEntity.getRequestPk());
        postWms.setContNo(trkEntity.getContNo());
        postWms.setCurPos(trkEntity.getToPos());
//        类型为[完成]
        postWms.setNoticeType("2");
        postWms.setCode(pCode);
        postWms.setResult(pMsg);
        postWms.setPostSt(0);
        postWms.setCreator(1002L);
        postWms.setUpdateDate(new Date());
        postWmsService.insert(postWms);
        logWorkService.workLogging(workName, task.getCtnrCode(), pCode,
                pMsg, null, workProc, "WCS系统", 10L);
    }
}
